package com.deman.framework.rpc.core;

import com.deman.framework.rpc.config.RpcSystemConfig;
import com.deman.framework.rpc.exception.CallBussninesException;
import com.deman.framework.rpc.exception.CallTimeOutException;
import com.deman.framework.rpc.exception.RejectResponseException;
import com.deman.framework.rpc.model.MessageRequest;
import com.deman.framework.rpc.model.MessageResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 调用核心类
 */
public class MessageCallBack {
    Logger logger= LoggerFactory.getLogger(MessageCallBack.class);
    private   MessageResponse response;
    private   MessageRequest request;

    private Lock lock=new ReentrantLock();

    private Condition finish = lock.newCondition();

    public MessageCallBack(MessageRequest messageRequest){
        this.request=messageRequest;
    }


    public Object start(){
        try {
            lock.lock();
            conditionAwait();
            if(this.response!=null){
                if(RpcSystemConfig.ERROR_CODE_SUCCESS.equalsIgnoreCase(response.getCode())){
                    return response.getResult();
                }else{
                    throw new CallBussninesException(RpcSystemConfig.ERROR_CODE_REJECT,response.getError());
                }
            }else {
                throw new RejectResponseException(RpcSystemConfig.ERROR_CODE_REJECT,"");
            }

        }finally {
            lock.unlock();
        }

    }

    public void over( MessageResponse messageResponse){
        try {
            lock.lock();
            this.response=messageResponse;
            finish.signalAll();
        }finally {
            lock.unlock();
        }

    }

    private void conditionAwait(){
        boolean timeOut=false;
        try {
            timeOut= finish.await(RpcSystemConfig.CALL_TIMEOUT, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            logger.error("await error :[{}]",e.getMessage());
        }
        if(!timeOut){
            throw new CallTimeOutException(RpcSystemConfig.ERROR_CODE_TIMEOUT,"调用超时");
        }
    }
}
